home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d4 / check6.arc / KERNEL.SYS < prev    next >
Encoding:
Text File  |  1988-06-26  |  26.7 KB  |  1,085 lines

  1. (***********************************************************)
  2. (*                                                         *)
  3. (*                TURBO GRAPHIX version 1.03A              *)
  4. (*                                                         *)
  5. (*                  Graphics system kernel                 *)
  6. (*                   Module version 1.03A                  *)
  7. (*                                                         *)
  8. (*                  Copyright (C) 1985 by                  *)
  9. (*                  BORLAND International                  *)
  10. (*                                                         *)
  11. (***********************************************************)
  12.  
  13. procedure GotoXYTurbo(X,Y:integer);
  14.   begin
  15.     GotoXY(X,Y);  { This will call Turbo's GotoXY }
  16.   end;
  17.  
  18. procedure GotoXY(X,Y:integer);   { Further calls to GotoXY will call this
  19.                                    procedure }
  20.   begin
  21.     if not GrafModeGlb then GotoXYTurbo(X,Y);
  22.     XTextGlb:=X;
  23.     YTextGlb:=Y;
  24.   end;
  25.  
  26. procedure ClrEOLTurbo;
  27.   begin
  28.     ClrEOL;  { This will call Turbo's ClrEOL }
  29.   end;
  30.  
  31. procedure ClrEOL;   { Further calls to ClrEOL will call this procedure }
  32.   var temp:integer;
  33.  
  34.   begin
  35.     if not GrafModeGlb then ClrEOLTurbo
  36.     else
  37.      begin
  38.       temp:=XTextGlb;
  39.       for XTextGlb:=temp to 80 do DC(32);
  40.       XTextGlb:=temp;
  41.      end;
  42.   end;
  43.  
  44. procedure error { declared in GRAPHIX.SYS: (ErrProc,ErrCode:integer) };
  45.   type string2=string[2];
  46.   var NLevels,PCValue,XLoc,YLoc:integer;
  47.       ch:char;
  48.  
  49.   function HexString(byt:byte):string2;
  50.     const hex:array [0..15] of char='0123456789ABCDEF';
  51.  
  52.     begin
  53.       HexString:=hex[byt shr 4] + hex[byt and 15];
  54.     end;
  55.  
  56. begin
  57.   if not (ErrProc in [0..MaxProcsGlb]) then
  58.    begin
  59.     LeaveGraphic;
  60.     writeln('FATAL ERROR 1: illegal procedure number ',ErrProc);
  61.     halt;
  62.    end;
  63.   if not (ErrCode in [0..MaxErrsGlb]) then
  64.    begin
  65.     LeaveGraphic;
  66.     writeln('FATAL ERROR 2: illegal error code ',ErrCode);
  67.     halt;
  68.    end;
  69.   ErrCodeGlb:=ErrCode;
  70.   if BrkGlb then LeaveGraphic;
  71.   if MessageGlb or BrkGlb then
  72.    begin
  73.     XLoc:=XTextGlb;
  74.     YLoc:=YTextGlb;
  75.     GotoXY(1,24);
  76.     ClrEOL;
  77.     writeln('Turbo Graphix error #',ErrCode,' in procedure #',ErrProc);
  78.     if MessageGlb then
  79.      begin
  80.       ClrEOL;
  81.       write('(',ErrorCode[ErrCode]^,' in ',ErrorProc[ErrProc]^,')');
  82.      end;
  83.    end;
  84.   if MessageGlb and BrkGlb then
  85.    begin
  86.     WriteLn;
  87.     WriteLn('Traceback:');
  88.     NLevels:=0;
  89.     repeat
  90.       inline($89/$EB/$8B/$8E/ NLevels /$09/$C9/$74/$05/$8B/$6E/
  91.              $00/$E2/$FB/$8B/$46/$02/$89/$DD/$89/$86/ PCValue );
  92.       if PCValue<>0 then
  93.         writeln(PcGlb,' : ',HexString(hi(PCValue-1)),HexString(lo(PCValue-1)));
  94.       NLevels:=NLevels+1;
  95.     until (NLevels>20) or (PCValue=0); { Trace back no more than 20 levels }
  96.     halt;
  97.    end
  98.   else if BrkGlb { and not MessageGlb } then halt
  99.   else if MessageGlb then
  100.    begin
  101.     write('.  Hit enter: ');
  102.     repeat
  103.       read(Kbd,Ch);
  104.     until (Ch=^M) or (Ch=^C);
  105.     if Ch=^C then
  106.      begin
  107.       LeaveGraphic;
  108.       halt;
  109.      end;
  110.     GotoXY(XLoc,YLoc);
  111.    end;
  112. end;
  113.  
  114. procedure SetBreakOff;
  115.   begin
  116.     BrkGlb:=false;
  117.   end;
  118.  
  119. procedure SetBreakOn;
  120.   begin
  121.     BrkGlb:=true;
  122.   end;
  123.  
  124. function GetErrorCode:byte;
  125.   begin
  126.     GetErrorCode:=ErrCodeGlb;
  127.     ErrCodeGlb:=0;
  128.   end;
  129.  
  130. procedure SetWindowModeOff;
  131.   begin
  132.     DirectModeGlb:=true;
  133.   end;
  134.  
  135. procedure SetWindowModeOn;
  136.   begin
  137.     DirectModeGlb:=false;
  138.   end;
  139.  
  140. procedure SetClippingOn;
  141.   begin
  142.     ClippingGlb:=true;
  143.   end;
  144.  
  145. procedure SetClippingOff;
  146.   begin
  147.     ClippingGlb:=false;
  148.   end;
  149.  
  150. procedure SetMessageOn;
  151.   begin
  152.     MessageGlb:=true;
  153.   end;
  154.  
  155. procedure SetMessageOff;
  156.   begin
  157.     MessageGlb:=false;
  158.   end;
  159.  
  160. procedure SetHeaderOn;
  161.   begin
  162.     HeaderGlb:=true;
  163.   end;
  164.  
  165. procedure SetHeaderOff;
  166.   begin
  167.     HeaderGlb:=false;
  168.   end;
  169.  
  170. procedure SetHeaderToTop;
  171.   begin
  172.     TopGlb:=true;
  173.   end;
  174.  
  175. procedure SetHeaderToBottom;
  176.   begin
  177.     TopGlb:=false;
  178.   end;
  179.  
  180. procedure RemoveHeader(i:integer);
  181.   begin
  182.     if i in [1..MaxWindowsGlb] then
  183.       with window[i] do
  184.        begin
  185.         drawn:=false;
  186.         top:=true;
  187.         header:='';
  188.        end
  189.     else error(22,2);
  190.   end;
  191.  
  192. procedure SetColorWhite;
  193.   begin
  194.     ColorGlb:=255;
  195.   end;
  196.  
  197. procedure SetColorBlack;
  198.   begin
  199.     ColorGlb:=0;
  200.   end;
  201.  
  202. function GetWindow:integer;
  203.   begin
  204.     GetWindow:=WindowNdxGlb;
  205.   end;
  206.  
  207. function GetColor:integer;
  208.   begin
  209.     GetColor:=ColorGlb;
  210.   end;
  211.  
  212. function clipping:boolean;
  213.   begin
  214.     clipping:=ClippingGlb;
  215.   end;
  216.  
  217. function WindowMode:boolean;
  218.   begin
  219.     WindowMode:=not DirectModeGlb;
  220.   end;
  221.  
  222. procedure SetScreenAspect(aspect:real);
  223.   begin
  224.     if aspect<>0.0 then AspectGlb:=abs(aspect);
  225.   end;
  226.  
  227. function GetScreenAspect:real;
  228.   begin
  229.     GetScreenAspect:=AspectGlb;
  230.   end;
  231.  
  232. procedure SetAspect(aspect:real);
  233.   begin
  234.     if aspect<>0.0 then AspectGlb:=abs(aspect)*AspectFactor;
  235.   end;
  236.  
  237. function GetAspect:real;
  238.   begin
  239.     GetAspect:=AspectGlb/AspectFactor;
  240.   end;
  241.  
  242. procedure SetLinestyle(ls:integer);
  243.   var i:integer;
  244.   const lsa:array [0..4] of byte=($FF,$88,$F8,$E4,$EE);
  245.  
  246.   begin
  247.     if not (ls in [0..4]) then ls:=ls and $FF + $100;
  248.     LineStyleGlb:=ls;
  249.     if ls<5 then ls:=lsa[ls];
  250.     for i:=0 to 7 do LineStyleArrayGlb[7-i]:=((ls shr i) and 1)<>0;
  251.     CntGlb:=7;
  252.   end;
  253.  
  254. function GetLinestyle:integer;
  255.   begin
  256.     GetLinestyle:=LinestyleGlb;
  257.   end;
  258.  
  259. procedure SetVStep(vs:integer);
  260.   begin
  261.     if vs>0 then VStepGlb:=vs;
  262.   end;
  263.  
  264. function GetVStep:integer;
  265.   begin
  266.     GetVStep:=VStepGlb;
  267.   end;
  268.  
  269. procedure DefineHeader(i:integer;hdr:wrkstring);
  270.   begin
  271.     if (i in [1..MaxWindowsGlb]) then window[i].header:=Hdr
  272.     else error(3,2);
  273.   end;
  274.  
  275. procedure SelectScreen(i:integer);
  276.   begin
  277.     if RamScreenGlb and (I=2) then GrafBase:=Seg(ScreenGlb^)
  278.     else GrafBase:=HardwareGrafBase;
  279.   end;
  280.  
  281. function GetScreen:byte;
  282.   begin
  283.     if GrafBase=HardwareGrafBase then GetScreen:=1 else GetScreen:=2;
  284.   end;
  285.  
  286. procedure DefineWorld(i:integer;
  287.                       X_1,Y_1,X_2,Y_2:real);
  288.   begin
  289.     if ((X_1<>X_2) and (Y_1<>Y_2)) and (i in [1..MaxWorldsGlb]) then
  290.       with world[i] do
  291.        begin
  292.         x1:=X_1;y1:=Y_2;x2:=X_2;y2:=Y_1;
  293.         if i>MaxWorldGlb then MaxWorldGlb:=i;
  294.        end
  295.     else if i in [1..MaxWorldsGlb] then error(1,3)
  296.     else error(1,2);
  297.   end;
  298.  
  299. procedure SelectWorld(i:integer);
  300.   begin
  301.     if (i in [1..MaxWorldGlb]) then
  302.       with world[i] do
  303.        begin
  304.         X1WldGlb:=x1;
  305.         Y1WldGlb:=y1;
  306.         X2WldGlb:=x2;
  307.         Y2WldGlb:=y2;
  308.        end
  309.     else error(2,2);
  310.   end;
  311.  
  312. procedure ReDefineWindow(i,X_1,Y_1,X_2,Y_2:integer);
  313.   begin
  314.     if (i in [1..MaxWindowsGlb]) and (X_1<=X_2) and (Y_1<=Y_2) and
  315.        (X_1>=0) and (X_2<=XMaxGlb) and (Y_1>=0) and (Y_2<=YMaxGlb) then
  316.       with window[i] do
  317.        begin
  318.         x1:=X_1;
  319.         y1:=Y_1;
  320.         x2:=X_2;
  321.         y2:=Y_2;
  322.         if i>MaxWindowGlb then MaxWindowGlb:=i;
  323.        end
  324.     else if i in [1..MaxWindowsGlb] then error(3,3)
  325.     else error(3,2);
  326.   end;
  327.  
  328. procedure DefineWindow(i,X_1,Y_1,X_2,Y_2:integer);
  329.   begin
  330.     ReDefineWindow(i,X_1,Y_1,X_2,Y_2);
  331.     with window[i] do
  332.      begin
  333.       header:='';
  334.       top:=true;
  335.       drawn:=false;
  336.      end;
  337.   end;
  338.  
  339. function TextLeft(TX,Boundary:integer):integer;
  340.   var TL:integer;
  341.   begin
  342.     TL:=((TX-1)*((XScreenMaxGlb+1) div 80)-Boundary) div 8;
  343.     if TL<0 then TL:=0
  344.     else if TL>XMaxGlb then TL:=XMaxGlb;
  345.     TextLeft:=TL;
  346.   end;
  347.  
  348. function TextRight(TX,Boundary:integer):integer;
  349.   var TR:integer;
  350.   begin
  351.     TR:=(XScreenMaxGlb+1) div 80;
  352.     TR:=(TX*TR+Boundary-1) div 8;
  353.     if TR<0 then TR:=0
  354.     else if TR>XMaxGlb then TR:=XMaxGlb;
  355.     TextRight:=TR;
  356.   end;
  357.  
  358. function TextUp(TY,Boundary:integer):integer;
  359.   var TU:integer;
  360.   begin
  361.     TU:=(TY-1)*((YMaxGlb+1) Div 25)-Boundary;
  362.     if TU<0 then TU:=0
  363.     else if TU>YMaxGlb then TU:=YMaxGlb;
  364.     TextUp:=TU;
  365.   end;
  366.  
  367. function TextDown(TY,Boundary:integer):integer;
  368.   var TD:integer;
  369.   begin
  370.     TD:=TY*((YMaxGlb+1) Div 25)+Boundary-1;
  371.     if TD<0 then TD:=0
  372.     else if TD>YMaxGlb then TD:=YMaxGlb;
  373.     TextDown:=TD;
  374.   end;
  375.  
  376. procedure DefineTextWindow(i,X1,Y1,X2,Y2,B:integer);
  377.   begin
  378.     DefineWindow(i,TextLeft(X1,B),TextUp(Y1,B),TextRight(X2,B),TextDown(Y2,B));
  379.   end;
  380.  
  381. procedure SelectWindow(i:integer);
  382.   begin
  383.     if (i in [1..MaxWindowGlb]) then
  384.       with window[i] do
  385.        begin
  386.         WindowNdxGlb:=i;
  387.         X1RefGlb:=x1;
  388.         Y1RefGlb:=y1;
  389.         X2RefGlb:=x2;
  390.         Y2RefGlb:=y2;
  391.         BxGlb:=((x2-x1) shl 3+7)/(X2WldGlb-X1WldGlb);
  392.         ByGlb:=(y2-y1)/(Y2WldGlb-Y1WldGlb);
  393.         AxGlb:=(x1 shl 3)-X1WldGlb*BxGlb;
  394.         AyGlb:=y1-Y1WldGlb*ByGlb;
  395.         if AxisGlb then
  396.          begin
  397.           AxisGlb:=false;
  398.           X1Glb:=0;
  399.           Y1Glb:=0;
  400.           X2Glb:=0;
  401.           Y2Glb:=0;
  402.          end;
  403.        end
  404.     else error(4,2);
  405.   end;
  406.  
  407. function WindowX(x:real):integer;
  408.   begin
  409.     WindowX:=trunc(AxGlb+BxGlb*x);
  410.   end;
  411.  
  412. function WindowY(y:real):integer;
  413.   begin
  414.     WindowY:=trunc(AyGlb+ByGlb*y);
  415.   end;
  416.  
  417. procedure InitGraphic;
  418.   var fil:file of CharArray;
  419.       tfile:text;
  420.       test:^integer;
  421.       temp:WrkString;
  422.       i:integer;
  423.  
  424.   begin
  425.     GotoXY(1,1);
  426.     if not HardwarePresent then
  427.      begin
  428.       ClrScr;
  429.       GotoXY(1,2);
  430.       writeln('Fatal error: graphics hardware not found or not properly activated');
  431.       halt;
  432.      end;
  433.     MessageGlb:=True;
  434.     BrkGlb:=False;
  435.     GrafModeGlb:=False;
  436.     GetMem(ErrorProc[0],16);
  437.     GetMem(ErrorCode[0],24);
  438.     ErrorProc[0]^:='InitGraphic';
  439.     ErrorCode[0]^:='ERROR.MSG missing';
  440.     assign(tfile,'error.msg');
  441.     {$I-} reset(tfile); {$I+}
  442.     if ioresult=0 then
  443.      begin
  444.       for i:=0 to MaxProcsGlb do
  445.        begin
  446.         readln(tfile,temp);
  447.         if i<>0 then GetMem(ErrorProc[i],length(temp)+1);
  448.         ErrorProc[i]^:=temp;
  449.        end;
  450.       for i:=0 to MaxErrsGlb do
  451.        begin
  452.         readln(tfile,temp);
  453.         if i<>0 then GetMem(ErrorCode[i],length(temp)+1);
  454.         ErrorCode[i]^:=temp;
  455.        end;
  456.       readln(tfile,PcGlb);
  457.       close(tfile);
  458.      end
  459.     else
  460.      begin
  461.       GetMem(ErrorProc[1],14);
  462.       ErrorProc[1]^:='** UNKNOWN **';
  463.       for i:=2 to MaxProcsGlb do
  464.         ErrorProc[i]:=ErrorProc[1];
  465.       for i:=1 to MaxErrsGlb do ErrorCode[i]:=ErrorProc[1];
  466.       error(0,0);
  467.      end;
  468.     for i:=1 to MaxWorldsGlb do
  469.       DefineWorld(i,0,0,XScreenMaxGlb,YMaxGlb);
  470.     MaxWorldGlb:=1;
  471.     for i:=1 to MaxWindowsGlb do
  472.      begin
  473.       DefineWindow(i,0,0,XMaxGlb,YMaxGlb);
  474.       with stack[i] do
  475.        begin
  476.         W.Size:=0;
  477.         Contents:=Nil;
  478.        end;
  479.       RemoveHeader(i);
  480.      end;
  481.     MaxWindowGlb:=1;
  482.     if CharFile<>'' then
  483.      begin
  484.       assign(fil,CharFile);
  485.       {$I-} reset(fil); {$I+}
  486.       if ioresult=0 then read(fil,CharSet)
  487.       else error(0,1);
  488.       close(fil);
  489.      end;
  490.     BrkGlb:=true;
  491.     if RamScreenGlb then
  492.      begin
  493.       AllocateRAMScreen;
  494.       SelectScreen(2);
  495.       ClearScreen;
  496.      end;
  497.     SelectScreen(1);
  498.     WindowNdxGlb:=1;
  499.     SelectWorld(1);
  500.     SelectWindow(1);
  501.     SetColorWhite;
  502.     SetClippingOn;
  503.     SetAspect(AspectFactor);
  504.     DirectModeGlb:=false;
  505.     PieGlb:=false;
  506.     SetMessageOn;
  507.     SetHeaderOff;
  508.     SetHeaderToTop;
  509.     ErrCodeGlb:=0;
  510.     SetLineStyle(0);
  511.     VStepGlb:=IVStepGlb;
  512.     EnterGraphic;
  513.     X1Glb:=0;
  514.     X2Glb:=0;
  515.     Y1Glb:=0;
  516.     Y2Glb:=0;
  517.     AxisGlb:=false;
  518.     HatchGlb:=false;
  519.   end;
  520.  
  521. procedure ResetWindows;
  522.   var i:integer;
  523.  
  524.   begin
  525.     for i:=1 to MaxWindowsGlb do
  526.      begin
  527.       DefineWindow(i,0,0,XMaxGlb,YMaxGlb);
  528.       RemoveHeader(i);
  529.      end;
  530.     SelectWindow(1);
  531.   end;
  532.  
  533. procedure ResetWorlds;
  534.   var i:integer;
  535.  
  536.   begin
  537.     for i:=1 to MaxWorldsGlb do
  538.       DefineWorld(i,0,0,XScreenMaxGlb,YMaxGlb);
  539.     SelectWorld(1);
  540.     SelectWindow(WindowNdxGlb);
  541.   end;
  542.  
  543. function clip(var x1,y1,x2,y2:integer):boolean;
  544.   var ix1,iy1,ix2,iy2,dummy,X1Loc,X2Loc:integer;
  545.       ClipLoc:boolean;
  546.  
  547.   function inside(x,xx1,xx2:integer):integer;
  548.     begin
  549.       inside:=0;
  550.       if x<xx1 then inside:=-1
  551.       else if x>xx2 then inside:=1;
  552.     end;
  553.  
  554.   begin
  555.     clip:=true;
  556.     ClipLoc:=true;
  557.     if ClippingGlb then
  558.      begin
  559.       if HatchGlb then
  560.        begin
  561.         X1Loc:=X1RefGlb;
  562.         X2Loc:=X2RefGlb;
  563.        end
  564.       else
  565.        begin
  566.         X1Loc:=X1RefGlb shl 3;
  567.         X2Loc:=X2RefGlb shl 3 +7;
  568.        end;
  569.       ix1:=inside(x1,X1Loc,X2Loc);
  570.       iy1:=inside(y1,Y1RefGlb,Y2RefGlb);
  571.       ix2:=inside(x2,X1Loc,X2Loc);
  572.       iy2:=inside(y2,Y1RefGlb,Y2RefGlb);
  573.       if (ix1 or ix2 or iy1 or iy2)<>0 then
  574.        begin
  575.         if x1<>x2 then
  576.          begin
  577.           if ix1<>0 then
  578.            begin
  579.             if ix1<0 then dummy:=X1Loc else dummy:=X2Loc;
  580.             if y2<>y1 then y1:=y1+trunc((y2-y1)/(x2-x1)*(dummy-x1));
  581.             x1:=dummy;
  582.            end;
  583.           if (ix2<>0) and (x1<>x2) then
  584.            begin
  585.             if ix2<0 then dummy:=X1Loc else dummy:=X2Loc;
  586.             if y2<>y1 then y2:=y1+trunc((y2-y1)/(x2-x1)*(dummy-x1));
  587.             x2:=dummy;
  588.            end;
  589.           iy1:=inside(y1,Y1RefGlb,Y2RefGlb);
  590.           iy2:=inside(y2,Y1RefGlb,Y2RefGlb);
  591.          end;
  592.         if y1<>y2 then
  593.          begin
  594.           if iy1<>0 then
  595.            begin
  596.             if iy1<0 then dummy:=Y1RefGlb else dummy:=Y2RefGlb;
  597.             if x1<>x2 then x1:=x1+trunc((x2-x1)/(y2-y1)*(dummy-y1));
  598.             y1:=dummy;
  599.            end;
  600.           if iy2<>0 then
  601.            begin
  602.             if iy2<0 then dummy:=Y1RefGlb else dummy:=Y2RefGlb;
  603.             if x1<>x2 then x2:=x1+trunc((x2-x1)/(y2-y1)*(dummy-y1));
  604.             y2:=dummy;
  605.            end;
  606.          end;
  607.         iy1:=inside(y1,Y1RefGlb,Y2RefGlb);
  608.         iy2:=inside(y2,Y1RefGlb,Y2RefGlb);
  609.         if (iy1<>0) or (iy2<>0) then ClipLoc:=false;
  610.         if ClipLoc then
  611.          begin
  612.           ix1:=inside(x1,X1Loc,X2Loc);
  613.           ix2:=inside(x2,X1Loc,X2Loc);
  614.           if (ix2<>0) or (ix1<>0) then ClipLoc:=false;
  615.          end;
  616.         clip:=ClipLoc;
  617.        end;
  618.      end;
  619.   end;
  620.  
  621. procedure DrawPoint(xr,yr:real);
  622.   var x,y:integer;
  623.  
  624.   begin
  625.     if DirectModeGlb then dp(trunc(xr),trunc(yr))
  626.     else
  627.      begin
  628.       x:=WindowX(xr);
  629.       y:=WindowY(yr);
  630.       if ClippingGlb then
  631.        begin
  632.         if (x>=X1RefGlb shl 3) and (x<X2RefGlb shl 3+7) then
  633.           if (y>=Y1RefGlb) and (y<=Y2RefGlb) then dp(x,y);
  634.        end
  635.       else dp(x,y);
  636.      end;
  637.   end;
  638.  
  639. function PointDrawn(xr,yr:real):boolean;
  640.   begin
  641.     if DirectModeGlb then PointDrawn:=PD(trunc(xr),trunc(yr))
  642.     else PointDrawn:=PD(WindowX(xr),WindowY(yr));
  643.   end;
  644.  
  645. procedure DrawLine(x1,y1,x2,y2:real);
  646.   var X1Loc,Y1Loc,X2Loc,Y2Loc:integer;
  647.  
  648.   procedure DrawLineDirect(x1,y1,x2,y2:integer);
  649.     var x,y,DeltaX,DeltaY,XStep,YStep,direction:integer;
  650.  
  651.     begin
  652.       x:=x1;
  653.       y:=y1;
  654.       XStep:=1;
  655.       YStep:=1;
  656.       if x1>x2 then XStep:=-1;
  657.       if y1>y2 then YStep:=-1;
  658.       DeltaX:=abs(x2-x1);
  659.       DeltaY:=abs(y2-y1);
  660.       if DeltaX=0 then direction:=-1
  661.       else direction:=0;
  662.       while not ((x=x2) and (y=y2)) do
  663.        begin
  664.         if LinestyleGlb=0 then dp(x,y)
  665.         else
  666.          begin
  667.           CntGlb:=(CntGlb+1) and 7;
  668.           if LineStyleArrayGlb[CntGlb] then dp(x,y);
  669.          end;
  670.         if direction<0 then
  671.          begin
  672.           y:=y+YStep;
  673.           direction:=direction+DeltaX;
  674.          end
  675.         else
  676.          begin
  677.           x:=x+XStep;
  678.           direction:=direction-DeltaY;
  679.          end;
  680.        end;
  681.     end;
  682.  
  683.   begin
  684.     if DirectModeGlb then
  685.       DrawLineDirect(trunc(x1),trunc(y1),trunc(x2),trunc(y2))
  686.     else
  687.      begin
  688.       X1Loc:=WindowX(x1);
  689.       Y1Loc:=WindowY(y1);
  690.       X2Loc:=WindowX(x2);
  691.       Y2Loc:=WindowY(y2);
  692.       if clip (X1Loc,Y1Loc,X2Loc,Y2Loc) then
  693.         DrawLineDirect(X1Loc,Y1Loc,X2Loc,Y2Loc);
  694.      end;
  695.   end;
  696.  
  697. procedure DrawLineClipped(x1,y1,x2,y2:integer);
  698.   begin
  699.     if clip(x1,y1,x2,y2) then DrawLine(x1,y1,x2,y2);
  700.   end;
  701.  
  702. procedure DrawCrossDiag(x,y,scale:integer);
  703.   begin
  704.     DrawLineClipped(x-scale,y+scale,x+scale+1,y-scale-1);
  705.     DrawLineClipped(x-scale,y-scale,x+scale+1,y+scale+1);
  706.   end;
  707.  
  708. procedure DrawWye(x,y,scale:integer);
  709.   begin
  710.     DrawLineClipped(x-scale,y-scale,x,y);
  711.     DrawLineClipped(x+scale,y-scale,x,y);
  712.     DrawLineClipped(x,y,x,y+scale);
  713.   end;
  714.  
  715. procedure DrawDiamond(x,y,scale:integer);
  716.   begin
  717.     DrawLineClipped(x-scale,y,x,y-scale-1);
  718.     DrawLineClipped(x,y-scale+1,x+scale,y+1);
  719.     DrawLineClipped(x+scale,y+1,x,y+scale);
  720.     DrawLineClipped(x,y+scale,x-scale,y);
  721.   end;
  722.  
  723. procedure DrawCircleDirect(xr,yr,r:integer; DirectModeLoc: boolean);
  724.   const n=14;
  725.   type Circ = array [1..n] of integer;
  726.   const x:Circ=(0,121,239,355,465,568,663,749,823,885,935,971,993,1000);
  727.   var xk1,xk2,yk1,yk2,xp1,yp1,xp2,yp2:integer;
  728.       xfact,yfact:real;
  729.       i:integer;
  730.  
  731.   procedure DrawLinW(X1,Y1,X2,Y2:integer);
  732.     var DrawIt: boolean;
  733.  
  734.     begin
  735.       DrawIt:=DirectModeLoc;
  736.       if not DrawIt then DrawIt:=Clip(X1,Y1,X2,Y2);
  737.       if DrawIt then DrawLine(X1,Y1,X2,Y2);
  738.     end;
  739.  
  740.   begin
  741.     xfact:=abs(r*0.001);
  742.     yfact:=xfact*AspectGlb;
  743.     if xfact>0.0 then
  744.      begin
  745.       xk1:=trunc(x[1]*xfact+0.5);
  746.       yk1:=trunc(x[n]*yfact+0.5);
  747.       for i:=2 to n do
  748.        begin
  749.         xk2:=trunc(x[i]*xfact+0.5);
  750.         yk2:=trunc(x[n-i+1]*yfact+0.5);
  751.         xp1:=xr-xk1;
  752.         yp1:=yr+yk1;
  753.         xp2:=xr-xk2;
  754.         yp2:=yr+yk2;
  755.         DrawLinW(xp1,yp1,xp2,yp2);
  756.         xp1:=xr+xk1;
  757.         xp2:=xr+xk2;
  758.         DrawLinW(xp1,yp1,xp2,yp2);
  759.         yp1:=yr-yk1;
  760.         yp2:=yr-yk2;
  761.         DrawLinW(xp1,yp1+1,xp2,yp2+1);
  762.         xp1:=xr-xk1;
  763.         xp2:=xr-xk2;
  764.         DrawLinW(xp1,yp1+1,xp2,yp2+1);
  765.         xk1:=xk2;
  766.         yk1:=yk2;
  767.        end;
  768.      end
  769.     else dp(xr,yr);
  770.   end;
  771.  
  772. procedure DrawCircle(X_R,Y_R,xradius:real);
  773.   var DirectModeLoc:boolean;
  774.  
  775.   begin { DrawCircle }
  776.     DirectModeLoc:=DirectModeGlb;
  777.     DirectModeGlb:=True;
  778.     if DirectModeLoc then DrawCircleDirect(trunc(X_R),trunc(Y_R),trunc(xradius),True)
  779.     else DrawCircleDirect(WindowX(X_R),WindowY(Y_R),trunc(xradius*100.0),False);
  780.     DirectModeGlb:=DirectModeLoc;
  781.   end;
  782.  
  783. procedure DrawCross(x1,y1,scale:integer);
  784.   begin
  785.     DrawLineClipped(x1-scale,y1,x1+scale+2,y1);
  786.     DrawLineClipped(x1,y1-scale,x1,y1+scale+1);
  787.   end;
  788.  
  789. procedure DrawStar(x,y,scale:integer);
  790.   begin
  791.     DrawLineClipped(x-scale,y+scale,x+scale+1,y-scale-1);
  792.     DrawLineClipped(x-scale,y-scale,x+scale+1,y+scale+1);
  793.     DrawLineClipped(x-scale-2,y,x+scale+4,y);
  794.   end;
  795.  
  796. procedure DrawSquareC(x1,y1,x2,y2:integer;
  797.                         fill:boolean);
  798.   var i:integer;
  799.  
  800.   procedure DSC(x1,x2,y:integer);
  801.     begin
  802.       if clip(x1,y,x2,y) then
  803.         if LineStyleGlb=0 then DrawStraight(x1,x2,y)
  804.         else DrawLine(x1,y,x2,y);
  805.     end;
  806.  
  807.   begin
  808.     if not fill then
  809.      begin
  810.       DSC(x1,x2,y1);
  811.       DrawLineClipped(x2,y1,x2,y2);
  812.       DSC(x1,x2,y2);
  813.       DrawLineClipped(x1,y2,x1,y1);
  814.      end
  815.     else
  816.     for i:=y2 to y1 do DSC(x1,x2,i);
  817.   end;
  818.  
  819. procedure DrawSquare(X1,Y1,X2,Y2:real;
  820.                      fill:boolean);
  821.   var i,x1loc,y1loc,x2loc,y2loc:integer;
  822.       DirectModeLoc:boolean;
  823.  
  824.   procedure DS(x1,x2,y:integer);
  825.     begin
  826.       if LineStyleGlb=0 then DrawStraight(x1,x2,y)
  827.       else DrawLine(x1,y,x2,y);
  828.     end;
  829.  
  830.   procedure DSC(x1,x2,y:integer);
  831.     begin
  832.       if clip(x1,y,x2,y) then DS(x1,x2,y);
  833.     end;
  834.  
  835.   procedure DrawSqr(x1,y1,x2,y2:integer;
  836.                     fill:boolean);
  837.     var i:integer;
  838.  
  839.     begin
  840.       if not fill then
  841.        begin
  842.         DS(x1,x2,y1);
  843.         DrawLine(x2,y1,x2,y2);
  844.         DS(x1,x2,y2);
  845.         DrawLine(x1,y2,x1,y1);
  846.        end
  847.       else
  848.       for i:=y1 to y2 do DS(x1,x2,i);
  849.     end;
  850.  
  851.   begin
  852.      if DirectModeGlb then DrawSqr(trunc(X1),trunc(Y1),trunc(X2),trunc(Y2),fill)
  853.     else
  854.      begin
  855.       DirectModeLoc:=DirectModeGlb;
  856.       DirectModeGlb:=true;
  857.       x1loc:=WindowX(X1);
  858.       y1loc:=WindowY(Y1);
  859.       x2loc:=WindowX(X2);
  860.       y2loc:=WindowY(Y2);
  861.       if not fill then
  862.        begin
  863.         DSC(x1loc,x2loc,y1loc);
  864.         DrawLineClipped(x2loc,y1loc,x2loc,y2loc);
  865.         DSC(x1loc,x2loc,y2loc);
  866.         DrawLineClipped(x1loc,y2loc,x1loc,y1loc);
  867.        end
  868.       else
  869.         for i:=y1loc to y2loc do DSC(x1loc,x2loc,i);
  870.       DirectModeGlb:=DirectModeLoc;
  871.      end;
  872.   end;
  873.  
  874. procedure DrawAscii(var x,y:integer;
  875.                     size,ch:byte);
  876.   var x1ref,x2ref,xpos,ypos,xstart,ystart,xend,yend,xx,yy: integer;
  877.       charbyte: byte;
  878.  
  879.   begin
  880.     x1ref:=X1RefGlb shl 3;
  881.     x2ref:=X2RefGlb shl 3+7;
  882.     for ypos:=0 to 5 do
  883.      begin
  884.       CharByte:=(CharSet[ch,(7-ypos) shr 1] shr ((ypos and 1) shl 2)) and $0F;
  885.       for xpos:=0 to 3 do
  886.         if (CharByte shr (3-xpos)) and 1<>0 then
  887.          begin
  888.           xstart:=x+xpos*size;
  889.           xend:=xstart+size-1;
  890.           ystart:=y+1+(ypos-2)*size;
  891.           yend:=ystart+size-1;
  892.           if ClippingGlb then
  893.            begin
  894.             if xstart<x1ref then xstart:=x1ref;
  895.             if xend>x2ref then xend:=x2ref;
  896.             if ystart<Y1RefGlb then ystart:=Y1RefGlb;
  897.             if yend>Y2RefGlb then yend:=Y2RefGlb;
  898.            end;
  899.           for yy:=ystart to yend do
  900.             for xx:=xstart to xend do
  901.               dp(xx,yy);
  902.          end;
  903.      end;
  904.      x:=x+size*6;
  905.    end;
  906.  
  907. procedure DrawText(x,y,scale:integer;
  908.                    txt:wrkstring);
  909.   var LineStyleLoc,code,AsciiValue,StringLen,i,SymbolScale,SymbolCode:integer;
  910.       DirectModeLoc:boolean;
  911.  
  912.   begin
  913.     DirectModeLoc:=DirectModeGlb;
  914.     DirectModeGlb:=true;
  915.     LineStyleLoc:=LinestyleGlb;
  916.     SetLineStyle(0);
  917.     StringLen:=length(txt);
  918.     i:=1;
  919.     while i<=StringLen do
  920.      begin
  921.       AsciiValue:=ord(txt[i]);
  922.       if AsciiValue=27 then
  923.        begin
  924.         SymbolScale:=scale;
  925.         i:=i+1;
  926.         if i<=StringLen then
  927.          begin
  928.           val(txt[i],SymbolCode,code);
  929.           if (i+2<=StringLen) and (ord(txt[i+1])=64) then
  930.            begin
  931.             val(txt[i+2],SymbolScale,code);
  932.             i:=i+2;
  933.            end;
  934.           case SymbolCode of
  935.             1:DrawCross(x+SymbolScale,y+scale,SymbolScale);
  936.             2:DrawCrossDiag(x+SymbolScale,y+scale,SymbolScale);
  937.             3,4: DrawSquareC(x,y+(SymbolScale shl 1)-1,x+(SymbolScale shl 1),
  938.                              y-1,(SymbolCode=4));
  939.             5:begin
  940.                 DrawDiamond(x+trunc(1.5*SymbolScale),y+SymbolScale-1,SymbolScale+1);
  941.                 x:=x+SymbolScale;
  942.               end;
  943.             6:DrawWye(x+SymbolScale,y+SymbolScale-1,SymbolScale);
  944.             7:begin
  945.                 DrawStar(x+SymbolScale shl 1,y+SymbolScale-1,SymbolScale);
  946.                 x:=x+SymbolScale shl 1;
  947.               end;
  948.             8:DrawCircleDirect(x+SymbolScale,y+(SymbolScale shr 1),SymbolScale+1,False);
  949.            end;
  950.           x:=x+3*SymbolScale;
  951.           SymbolScale:=scale;
  952.          end;
  953.        end
  954.       else DrawAscii(x,y,scale,AsciiValue);
  955.       i:=i+1;
  956.            end;
  957.     DirectModeGlb:=DirectModeLoc;
  958.     SetLineStyle(LineStyleLoc);
  959.   end;
  960.  
  961. procedure DrawTextW(x,y:real;
  962.                     scale:integer;
  963.                     txt:wrkstring);
  964.   begin
  965.     if DirectModeGlb then DrawText(trunc(x),trunc(y),scale,txt)
  966.     else DrawText(WindowX(x),WindowY(y),scale,txt);
  967.   end;
  968.  
  969. procedure DrawBorder;
  970.   var ClipLoc,DirectModeLoc:boolean;
  971.       xl1,xl2:integer;
  972.  
  973.   procedure DrawHeaderBackground(y1,y2:integer);
  974.     var i:integer;
  975.  
  976.     begin
  977.       for i:=y1 to y2 do DrawStraight(xl1,xl2,i);
  978.     end;
  979.  
  980.   procedure DrawHeader;
  981.     var Y1Hdr,Y2Hdr,yl1,yl2:integer;
  982.     begin
  983.       with window[WindowNdxGlb] do
  984.        begin
  985.         if drawn then
  986.           if top then
  987.            begin
  988.             ReDefineWindow(WindowNdxGlb,X1RefGlb,Y1RefGlb-HeaderSizeGlb,X2RefGlb,Y2RefGlb);
  989.             SelectWindow(WindowNdxGlb);
  990.            end
  991.           else
  992.            begin
  993.             ReDefineWindow(WindowNdxGlb,X1RefGlb,Y1RefGlb,X2RefGlb,Y2RefGlb+HeaderSizeGlb);
  994.             SelectWindow(WindowNdxGlb);
  995.            end;
  996.         if TopGlb then
  997.          begin
  998.           yl1:=Y1RefGlb+HeaderSizeGlb;
  999.           yl2:=Y2RefGlb;
  1000.           Y1Hdr:=Y1RefGlb;
  1001.           Y2Hdr:=Y1RefGlb+HeaderSizeGlb-1;
  1002.          end
  1003.         else
  1004.          begin
  1005.           yl1:=Y1RefGlb;
  1006.           yl2:=Y2RefGlb-HeaderSizeGlb;
  1007.           Y1Hdr:=Y2RefGlb-HeaderSizeGlb+1;
  1008.           Y2Hdr:=Y2RefGlb;
  1009.          end;
  1010.         top:=TopGlb;
  1011.         ReDefineWindow(WindowNdxGlb,X1RefGlb,yl1,X2RefGlb,yl2);
  1012.         SelectWindow(WindowNdxGlb);
  1013.         DrawHeaderBackground(Y1Hdr,Y2Hdr);
  1014.         ColorGlb:=255-ColorGlb;
  1015.         DrawText(xl1+2+(xl2-xl1-length(header)*6) shr 1,Y1Hdr+3,1,header);
  1016.         DrawSquare(xl1,Y1Hdr,xl2,Y2Hdr,false);
  1017.         ColorGlb:=255-ColorGlb;
  1018.         DrawSquare(xl1,Y1RefGlb,xl2,Y2RefGlb,false);
  1019.         drawn:=true;
  1020.       end;
  1021.     end;
  1022.  
  1023.   begin
  1024.     DirectModeLoc:=DirectModeGlb;
  1025.     DirectModeGlb:=true;
  1026.     ClipLoc:=ClippingGlb;
  1027.     ClippingGlb:=false;
  1028.     xl1:=X1RefGlb shl 3;
  1029.     xl2:=X2RefGlb shl 3+7;
  1030.     with window[WindowNdxGlb] do
  1031.       if ((HeaderGlb) and (length(header)>0)) and (y2-y1>HeaderSizeGlb) and
  1032.          ((length(header)*6)<abs(xl2-xl1)-4) then
  1033.         DrawHeader
  1034.       else
  1035.        begin
  1036.         drawn:=false;
  1037.         DrawSquare(xl1,Y1RefGlb,xl2,Y2RefGlb,false);
  1038.        end;
  1039.     DirectModeGlb:=DirectModeLoc;
  1040.     ClippingGlb:=ClipLoc;
  1041.   end;
  1042.  
  1043. procedure hardcopy(inverse:boolean;mode:byte); { EPSON }
  1044.   var i,j,top:integer;
  1045.       ColorLoc,PrintByte:byte;
  1046.  
  1047.   procedure doline(top:integer);
  1048.     function ConstructByte(j,i:integer):byte;
  1049.       const Bits:array [0..7] of byte=(128,64,32,16,8,4,2,1);
  1050.       var CByte,k:byte;
  1051.       begin
  1052.         i:=i shl 3;
  1053.         CByte:=0;
  1054.         for k:=0 to top do
  1055.           if PD(j,i+k) then CByte:=CByte or Bits[k];
  1056.         ConstructByte:=CByte;
  1057.       end;
  1058.     begin
  1059.       if mode=1 then write(lst,^['L')
  1060.       else write(lst,^['*',chr(mode));
  1061.       write(lst,chr(lo(XScreenMaxGlb+1)),chr(Hi(XScreenMaxGlb+1)));
  1062.       for j:=0 to XScreenMaxGlb do
  1063.        begin
  1064.         PrintByte:=ConstructByte(j,i);
  1065.         if inverse then PrintByte:=not PrintByte;
  1066.         write(lst,chr(PrintByte));
  1067.        end;
  1068.       if mode<>4 then writeln(lst);
  1069.     end;
  1070.  
  1071.   begin
  1072.     top:=7;
  1073.     ColorLoc:=ColorGlb;
  1074.     ColorGlb:=255;
  1075.     mode:=mode and 7;
  1076.     if (mode=5) or (mode=0) then mode:=4;
  1077.     write(lst,^['3'#24);
  1078.     for i:=0 to ((YMaxGlb+1) shr 3)-1 do doline(7);
  1079.     i:=((YMaxGlb+1) shr 3);
  1080.     if (YMaxGlb+1) and 7<>0 then
  1081.       doline((YMaxGlb+1) and 7);
  1082.     writeln(lst,^['2');
  1083.     ColorGlb:=ColorLoc;
  1084.   end;
  1085.